package org.redr.canvas;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class RedREnviron
{
	public static HashMap<String, String> version; // = new HashMap<String, String>();
	public static HashMap<String, File> directoryNames; // = getDirectoryNames(new File("RootDir"));
	//public HashMap<String, File> directories = new HashMap<String, File>();
	public static HashMap<String, Object> settings; // = new HashMap<String, Object>();
	
	public void setDirectories(String root)
	{
		File rootFile = new File(root);
		if (!rootFile.exists())
		{
			return; // should change to throw an exception
		}
		directoryNames = getDirectoryNames(rootFile);
		getVersion();
		loadSettings();
		
	}
	
	public String _(String s)
	{
		return s;
	}
	
	public File pathJoin(Object...strings )
	{
		return OSPath.pathJoin(strings);
	}
	
	public HashMap<String, File> getDirectoryNames(File rootDir)
	{
    //"""Return a dictionary with Red-R directories."""
		HashMap<String, File> dirs = new HashMap<String, File>();
		HashMap<String, File> createDir = new HashMap<String, File>();
		
		dirs.put("redRDir", rootDir);
	    dirs.put("canvasDir", pathJoin(rootDir, "canvas")); // , pathJoin(dirs["redRDir"], "canvas")
	    dirs.put("canvasIconsDir", pathJoin(rootDir, "canvas", "icons")); // , pathJoin(dirs["redRDir"], "canvas","icons")
	    dirs.put("widgetDir", pathJoin(rootDir, "libraries"));
	    //dirs["devAddonDir"] , pathJoin(os.path.split(dirs["redRDir"])[0], "RedRDevAddOn")
	    dirs.put("libraryDir", pathJoin(rootDir, "libraries"));
	    //dirs.put("qtWidgetsDir" pathJoin(rootDir, "libraries", "base", "qtWidgets"));
	    //dirs["redRSignalsDir"] , pathJoin(dirs["redRDir"], "libraries","base","signalClasses")
	    dirs.put("examplesDir", pathJoin(rootDir, "Examples"));
	    dirs.put("includes", pathJoin(rootDir, "includes"));
	    //dirs.put("picsDir", pathJoin(dirs["widgetDir"],"base", "icons")
	    
	    /*
	    ###############################
	    ## Set system specific paths##
	    ###############################
	    
	    
	    ####Windows#####
	    if sys.platform=="win32":
	        ### architecture specific ####
	        dirs["RDir"] , pathJoin(os.path.split(dirs["redRDir"])[0], "R", "R-2.11.1")        
	        dirs["osSpecific"] , pathJoin(dirs["redRDir"], "win32")
	        #dirs["rpyDir"] , pathJoin(dirs["redRDir"], "win32", "rpy3")
	        
	        createDir["settingsDir"] , pathJoin(os.environ["APPDATA"],"red-r")
	        objShell = win32com.client.Dispatch("WScript.Shell")
	        dirs["documentsDir"] , pathJoin(objShell.SpecialFolders("MyDocuments"))
	        dirs["RlibPath"] , pathJoin(dirs["RDir"], "library").replace("\\","/")
	
	    ####Mac#####
	    elif sys.platform == "darwin":
	         dirs["RDir"] = "/Applications/Red-R.app/R/R.framework/Resources/"        
	         dirs["osSpecific"] , pathJoin(dirs["redRDir"], "mac")
	         dirs["rpyDir"] , pathJoin(dirs["redRDir"], "mac", "rpy3")
	         createDir["settingsDir"] , pathJoin(os.environ["HOME"], ".red-r")        
	         dirs["documentsDir"] , pathJoin(os.path.expanduser("~"), "Red-R")
	         dirs["RlibPath"] , pathJoin(dirs["RDir"], "library")
	
	    ####Linux#####
	    else:
	         print "loading linux files"
     
	    import platform
         bit = platform.architecture()[0]
         if bit == "32bit":
            dirs["RDir"] , pathJoin(os.path.split(dirs["redRDir"])[0], "R", "R-2.11.1")        
            dirs["osSpecific"] , pathJoin(dirs["redRDir"], "linux32")
            dirs["rpyDir"] , pathJoin(dirs["redRDir"], "linux32", "rpy3")
         else:
            print "loading 64bit linux"
            dirs["RDir"] , pathJoin(os.path.split(dirs["redRDir"])[0], "R", "R-2.11.1")        
            dirs["osSpecific"] , pathJoin(dirs["redRDir"], "linux64")
            dirs["rpyDir"] , pathJoin(dirs["redRDir"], "linux64", "rpy3")
         */
	    
         createDir.put("settingsDir", pathJoin(System.getProperty("user.home"), ".red-r"));        
         dirs.put("documentsDir", new File(System.getProperty("user.home")));
         createDir.put("RlibPath", pathJoin(createDir.get("settingsDir"), "packages")); // a special path for our R libraries.
	    /*
	    ###########################
	    ## Red-R settings dir######
	    ###########################
		*/
	         
	    createDir.put("reportsDir", pathJoin(createDir.get("settingsDir"), "RedRReports"));
	    createDir.put("logsDir", pathJoin(createDir.get("settingsDir"), "RedRlogs"));
	    createDir.put("canvasSettingsDir", pathJoin(createDir.get("settingsDir"), "RedRCanvas")); 
	    createDir.put("tempDirHolder", pathJoin(createDir.get("settingsDir"), "RedRTemp"));
	    createDir.put("widgetSettingsDir", pathJoin(createDir.get("settingsDir"), "RedRWidgetSettings"));
	    createDir.put("downloadsDir", pathJoin(createDir.get("settingsDir"), "downloads"));
	    /*
	    ###########################
	    ## User doc dirs     ######
	    ###########################
	    */
	    createDir.put("templatesDir", pathJoin(dirs.get("documentsDir"), "Red-R", "Templates"));    
	    createDir.put("schemaDir", pathJoin(dirs.get("documentsDir"),"Red-R", "Schemas"));
	    
	    createDirectories(createDir);
	    dirs.putAll(createDir);        
	    return dirs;
	}
	
    private void createDirectories(HashMap<String, File> createDir)
    {
    	Iterator<File> createIterator = createDir.values().iterator();
    	while (createIterator.hasNext())
    	{
    		File thisFile = createIterator.next();
    		if (!thisFile.exists())
    		{
    			thisFile.mkdirs();
    		}
    	}
    }
    
    private void setTempDir(String temp)
    {
	    File tempDir = pathJoin(directoryNames.get("tempDirHolder"), temp); 
	    tempDir.mkdirs();
	    directoryNames.put("tempDir", tempDir);
    }
    
    @SuppressWarnings("unchecked")
	private void loadSettings()
    {
    	
        
        settings.put("id", String.valueOf(System.currentTimeMillis()));
        setTempDir("temp_"+ settings.get("id")); // make the temp directory

        settings.put("widgetListType", 3);
        settings.put("iconSize", "40 x 40");
        settings.put("toolbarIconSize", 1);
        settings.put("toolboxWidth", 200);
        settings.put("schemeIconSize", 2);
        settings.put("snapToGrid", 1);
        settings.put("helpMode", true);
        settings.put("minSeverity", 5);
        settings.put("saveWidgetsPosition", 1);
        //# settings.put("widgetSelectedColor", (0, 255, 0));
        //# settings.put("widgetActiveColor", (0,0,255))
        //# settings.put("lineColor", (0,255,0))
        
        settings.put("exceptionLevel", 5);
        settings.put("WidgetTabs", new Vector<String>());
        
        settings.put("workingDir", directoryNames.get("documentsDir"));
        settings.put("saveSchemaDir", directoryNames.get("documentsDir"));
        settings.put("saveApplicationDir", directoryNames.get("canvasSettingsDir"));
        settings.put("showSignalNames", 1);
        
        settings.put("canvasWidth", 900);
        settings.put("canvasHeight", 700);
        
        HashMap<String, Boolean> dockState = new HashMap<String, Boolean>();
        
        dockState.put("notesBox", true);
        dockState.put("outputBox", true);
        dockState.put("widgetBox", true);
        settings.put("dockState", dockState);
            
        settings.put("useDefaultPalette", 0);

        settings.put("CRANrepos","http://cran.r-project.org");
        settings.put("keepForXDays", 7);
        
        settings.put("lastUpdateCheckPackages",0);
        settings.put("checkForPackageUpdates",true);
        
        settings.put("checkForUpdates",true);
        settings.put("ignoredUpdates", null);
        
        settings.put("lastUpdateCheck",0);
        settings.put("updateAvailable", false);
        settings.put("updatesRepository", "http://www.red-r.org/redr_updates/Red-R-" + version.get("REDRVERSION"));
        
        settings.put("dontAskBeforeClose", 0);
        settings.put("askBeforeWidgetDelete", 1);
        
        settings.put("writeLogFile", 1);
        settings.put("logsDir", directoryNames.get("logsDir"));
        settings.put("uploadError", 0);
        settings.put("askToUploadError", 0);
        
        settings.put("focusOnCatchException", 1);
        settings.put("focusOnCatchOutput" , 0);
        settings.put("printOutputInStatusBar", 0);
        settings.put("printExceptionInStatusBar", 0);
        settings.put("outputVerbosity", 3);
        settings.put("displayTraceback", 0);
        
        settings.put("ocShow", 1);
        settings.put("owShow", 0);
        settings.put("ocInfo", 1);
        settings.put("owInfo", 1);
        settings.put("ocWarning", 1);
        settings.put("owWarning", 1);
        settings.put("ocError", 1);
        settings.put("owError", 1);
        
        settings.put("synchronizeHelp", 1);
        settings.put("firstLoad", 1);
        settings.put("email", "");
        settings.put("canContact", 0);
        Vector<File> templateDirectories = new Vector<File>();
        templateDirectories.add(directoryNames.get("templatesDir"));
        settings.put("templateDirectories", templateDirectories);
        
        /*
        //## language settings, these settings exist so that we can detect the language of the system
        
        settings.put("language", OrderedDict([("en_EN.ISO8859-1", u"English"), ("fr_FR.ISO8859-1", u"Fran\u00E7aise"), ("de_DE.ISO8859-1", u"Deutsch"), ("latin", "Latin")]))
        
        settings["availablelanguages"] = OrderedDict([("en_EN.ISO8859-1", u"English"), ("fr_FR.ISO8859-1", u"Fran\u00E7aise"), ("de_DE.ISO8859-1", u"Deutsch"), ("latin", "Latin")])
        		try:
                    filename , pathJoin(directoryNames["canvasSettingsDir"], "orngCanvas.ini")
                    if os.path.exists(filename):
                        try:
                            settings = cPickle.load(open(filename, "rb"))
                        except:
                            #redRLog.log(redRLog.REDRCORE, redRLog.ERROR, redRLog.formatException())
                            pass
                except Exception as inst:
                    print unicode(inst)
        */
        File filename = pathJoin(directoryNames.get("canvasSettingsDir"), "redRCanvas.ser");
        FileInputStream fis = null;
        ObjectInputStream in = null;
        HashMap<String, Object> oldSettings = new HashMap<String, Object>();
        try
        {
            fis = new FileInputStream(filename);
            in = new ObjectInputStream(fis);
            oldSettings = (HashMap<String, Object>) in.readObject();
        	in.close();
        }
        catch(IOException ex)
        {
        	ex.printStackTrace();
        }
        catch(ClassNotFoundException ex)
        {
        	ex.printStackTrace();
        }
        catch(Exception ex)
        {
        	ex.printStackTrace();
        }
        settings.putAll(oldSettings);
        //return settings

    }
    
    public void saveSettings()
    {
    	FileOutputStream fos = null;
    	ObjectOutputStream out = null;
    	try
    	{
    		fos = new FileOutputStream(pathJoin(directoryNames.get("canvasSettingsDir"), "redRCanvas.ser"));
    		out = new ObjectOutputStream(fos);
    		out.writeObject(settings);
    		out.close();
    	}
    	catch(IOException e)
    	{
    		e.printStackTrace();
    	}
    }
    
    private void getVersion()
    {
    	//  version = {"NAME": "Red-R", "REDRVERSION":"0", "TYPE":"0", "DATE":"2000.1.1", "SVNVERSION":"0"}
        //return version
    	
    	// !define\s(\S+)\s\"(.*?)\"//
    	Pattern defsearch = Pattern.compile("!define\\s(\\S+)\\s\"(.*?)\""); 
    	
    	version.put("NAME", "Red-R");
    	version.put("REDRVERSION", "0");
    	version.put("TYPE", "0");
    	version.put("DATE", "2012.1.10"); //the base date of compilation
    	version.put("UPDATEVERSION", "0");
    	
    	try
    	{
	    	BufferedReader in = new BufferedReader(new FileReader(pathJoin(directoryNames.get("redRDir"), "version.txt").toString()));
	    	String str;
	    	while ((str = in.readLine()) != null)
	    	{
	    		
	    		Matcher matcher = defsearch.matcher(str);
	    		boolean matchFound = matcher.find();
	    		if (matchFound)
	    		{
	    			version.put(matcher.group(1), matcher.group(2));
	    		}
	    		
	    	}
    	}
    	catch (Exception e)
    	{
    		e.printStackTrace();
    	}
    }
}

